package com.yb.xczx.cloud.auth.oauth2.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yb.xczx.cloud.auth.entity.Oauth2RegisteredClient;
import com.yb.xczx.cloud.auth.service.IOauth2RegisteredClientService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.util.Objects;

/**
 * Copyright (C), 2022-2023, 姚兵
 * Author: 32210
 * Date: 2023/5/21 15:09
 * FileName: XczxRegisteredClientRepository
 * Description:
 */

@Slf4j
public class XczxRegisteredClientRepository implements RegisteredClientRepository, CommandLineRunner {

    @Autowired
    IOauth2RegisteredClientService oauth2RegisteredClientService;

    private RegisteredClient[] registeredClients;

    public XczxRegisteredClientRepository(){

    }

    public XczxRegisteredClientRepository(RegisteredClient ...registeredClients){
       this.registeredClients=registeredClients;
    }
    @Override
    public void save(RegisteredClient registeredClient) {

        Oauth2RegisteredClient oauth2RegisteredClient = new Oauth2RegisteredClient();
        BeanUtils.copyProperties(registeredClient,oauth2RegisteredClient);
        oauth2RegisteredClientService.save(oauth2RegisteredClient);
    }

    @Override
    public RegisteredClient findById(String id) {

        Oauth2RegisteredClient oauth2RegisteredClient = oauth2RegisteredClientService.getById(id);

        if(Objects.isNull(oauth2RegisteredClient)){
            return null;
        }

        return RegisteredClient.withId(oauth2RegisteredClient.getId())
                .clientId(oauth2RegisteredClient.getClientId())
                .clientSecret(oauth2RegisteredClient.getClientSecret())
                .scopes(strings -> {strings.addAll(oauth2RegisteredClient.getScopes());})
                .redirectUris(uris->{uris.addAll(oauth2RegisteredClient.getRedirectUris());})
                .clientAuthenticationMethods(methods->{methods.addAll(oauth2RegisteredClient.getClientAuthenticationMethods());})
                .authorizationGrantTypes(authorizationGrantTypes -> {authorizationGrantTypes.addAll(oauth2RegisteredClient.getAuthorizationGrantTypes());})
                .clientIdIssuedAt(oauth2RegisteredClient.getClientIdIssuedAt())
                .clientSecretExpiresAt(oauth2RegisteredClient.getClientSecretExpiresAt())
                .clientName(oauth2RegisteredClient.getClientName())
                .tokenSettings(oauth2RegisteredClient.getTokenSettings())
                .clientSettings(oauth2RegisteredClient.getClientSettings())
                .build();
    }

    @Override
    public RegisteredClient findByClientId(String clientId) {
        Oauth2RegisteredClient oauth2RegisteredClient = oauth2RegisteredClientService.getOne(new LambdaQueryWrapper<Oauth2RegisteredClient>().eq(Oauth2RegisteredClient::getClientId, clientId));

        if(Objects.isNull(oauth2RegisteredClient)){
            return null;
        }

        return RegisteredClient.withId(oauth2RegisteredClient.getId())
                .clientId(oauth2RegisteredClient.getClientId())
                .clientSecret(oauth2RegisteredClient.getClientSecret())
                .scopes(strings -> {strings.addAll(oauth2RegisteredClient.getScopes());})
                .redirectUris(uris->{uris.addAll(oauth2RegisteredClient.getRedirectUris());})
                .clientAuthenticationMethods(methods->{methods.addAll(oauth2RegisteredClient.getClientAuthenticationMethods());})
                .authorizationGrantTypes(authorizationGrantTypes -> {authorizationGrantTypes.addAll(oauth2RegisteredClient.getAuthorizationGrantTypes());})
                .clientIdIssuedAt(oauth2RegisteredClient.getClientIdIssuedAt())
                .clientSecretExpiresAt(oauth2RegisteredClient.getClientSecretExpiresAt())
                .clientName(oauth2RegisteredClient.getClientName())
                .tokenSettings(oauth2RegisteredClient.getTokenSettings())
                .clientSettings(oauth2RegisteredClient.getClientSettings())
                .build();
    }


    @Override
    public void run(String... args) throws Exception {

        log.info("XczxRegisteredClientRepository init begin:{}");
        if(this.registeredClients.length==0){
            return;
        }
        for (RegisteredClient registeredClient : this.registeredClients) {

            if(this.oauth2RegisteredClientService.getBaseMapper().exists(new LambdaQueryWrapper<Oauth2RegisteredClient>().eq(Oauth2RegisteredClient::getClientId,registeredClient.getClientId()))){
                continue;
            }

            this.save(registeredClient);
        }
        log.info("XczxRegisteredClientRepository init end:{}");
    }
}
